package com.example.user.config;

/**
 * Author:汪彬彬
 * date:2024/11/20 14:48
 */

import com.example.commons.util.DateUtils;
import com.example.commons.util.RedisUtils;

import java.util.concurrent.TimeUnit;

/**
 * 令牌通算法
 */

public class TokenBucket {

     //前缀
     private static String PREFIX = "token_bucket_";

    //令牌桶容量
     static Integer maxPermits = 5;

    // 每个手机号码一分钟内只能发送一条短信
    static int permitsPerMinute = 1;

     public static Boolean tryAcquire(String phoneNum){
          // 获取当前时间戳
          long now = System.currentTimeMillis();
          String key = PREFIX + phoneNum;
          int tokens = Integer.parseInt(RedisUtils.StringOps.get(key) == null ?
                  String.valueOf(maxPermits) : RedisUtils.StringOps.get(key));
          if(tokens<=0){
              throw new RuntimeException("令牌桶用完了");
          }else {
              // 计算令牌桶上次填充的时间戳
              long lastRefillTime = Long.parseLong(RedisUtils.StringOps.get(key + "_last_refill_time")
                      == null ? "0" : RedisUtils.StringOps.get(key + "_last_refill_time"));
              // 计算当前时间与上次填充时间的时间差
              long timeSinceLast = now - (lastRefillTime+(1000*60/permitsPerMinute));
              // 计算需要填充的令牌数
              if(timeSinceLast>=0){
                  tokens--;
                  long ex = DateUtils.getNextDaytoLong()-now;
                  RedisUtils.StringOps.setEx(key,String.valueOf(tokens),ex, TimeUnit.MILLISECONDS);
                  RedisUtils.StringOps.setEx(key+"_last_refill_time",String.valueOf(now),ex, TimeUnit.MILLISECONDS);
                return  true;
              } else {
                  throw new RuntimeException("请勿频繁操作，稍后再试");
              }

          }

     }

    public static void main(String[] args) {

        long now = System.currentTimeMillis();
        System.out.println(now);
    }

}
